package com.lincoln.framework.interfaces;

import com.lincoln.framework.bean.ProtocolContext;
import com.lincoln.util.ResizingArrayStack;
import lombok.Data;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 设备信息
 *
 * @author lincoln
 */
@Data
public abstract class BaseDeviceInfo {
    /**
     * 在attributes中存储未携带登陆状态请求服务器的次数
     */
    public static final String NO_LOGIN_REQUEST_TIME = "NO_LOGIN_REQUEST_TIME";
    /**
     * 总请求次数
     */
    public static final String REQUEST_TIME = "REQUEST_TIME";

    /**
     * 内部使用uuid生成的
     */
    protected String clientId;

    /**
     * 设备类型,不同的设备类型放置的map不同
     */
    protected int deviceType = -1;

    /**
     * 使用的协议号
     */
    protected int protocolType = -1;

    /**
     * 额外信息
     */
    protected Map<String, Object> attributes = new ConcurrentHashMap<>();

    /**
     * 当前ip
     */
    protected String ip;

    /**
     * 所连接的端口号,未知使用-1,影响不大
     */
    protected int port;

    /**
     * 不同的deviceType有不同的发送方式
     */
    protected Object msgSender;

    /**
     * 验证登陆状态,是则从未登录列表中去掉
     *
     * @return
     */
    public boolean login() {
        if (isLogin()) {
            ProtocolContext.removeNoLogin(clientId);
            return true;
        } else {
            return false;
        }
    }

    /**
     * z注销客户端,断开服务器连接
     *
     * @return
     */
    public abstract boolean logout();

    /**
     * 是否是登陆了的
     *
     * @return
     */
    public abstract boolean isLogin();

    /**
     * 获取主键(设备号,mac地址,imei等唯一值)
     *
     * @return
     */
    public abstract String getPrimaryKey();

    /**
     * 获取设备类型
     *
     * @return
     */
    public abstract Integer getDeviceType();

    /**
     * 获取设备类型
     *
     * @return
     */
    public abstract Integer getProtocolType();


    /**
     * 向此设备发送一个消息
     *
     * @param protocol
     * @return
     */
    public abstract boolean sendMsg(BaseProtocol protocol);

    /**
     * 向此设备发送一个消息
     *
     * @param data
     * @return
     */
    public abstract boolean sendMsg(byte[] data);

    //netty分包用
    // 用于识别当前帧首
    protected ResizingArrayStack<Byte> headerCache = new ResizingArrayStack<>();
    // 用于识别当前帧尾
    protected ResizingArrayStack<Byte> tailCache = new ResizingArrayStack<>();
    // 当前缓存的包
    protected ResizingArrayStack<Byte> cache = new ResizingArrayStack<>();
    // 当前是否正在读入帧数据
    protected boolean isRecord = false;
}
